package com.gmrz.uaf.servlet.v1.handler;

import com.gmrz.uaf.common.Constants;
import com.gmrz.uaf.protocol.v1.json.UAFSchemaBuilder;
import com.gmrz.uaf.server.ServerContext;
import com.gmrz.uaf.servlet.v1.request.GetUserInfoContext;
import com.gmrz.uaf.servlet.v1.request.ReceiveReqPayload;
import com.gmrz.uaf.servlet.v1.response.FidoRespPayload;
import com.gmrz.uaf.servlet.v1.validation.PayloadValidationException;
import com.gmrz.uaf.servlet.v1.validation.RestValidator;
import com.gmrz.util.Strings;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.util.*;

public class UAFDevicesInfoRequestHandler extends UAFBaseHandler {
    private static final Logger LOG = LogManager.getLogger(UAFDevicesInfoRequestHandler.class);

    /**
     * {
     * "context":{
     * "userName":"test-1257878",
     * "appID":"1103",
     * "deviceID":"+xkVOHTXVzFOpP+YzyHsZhFbn4ldgiWXGZ\/eGL5NHB7hXTn46LeqOPfYQk+YO9QL"
     * }
     * }
     *
     * @param request
     * @return {"statusCode":1200,"description":"OK",
     * "uafRequest":[{"userName":"3068b2104a98b0484c20671b6ceacebc822cf135","custNo":"test-1257878",
     * "aaid":"004A#9999","keyid":"gQDIIICZudGQJCq4x57xzkEH4usK1TDE5p69I8W80Hs",
     * "keyFormat":"256","signCounter":0,"regCounter":0,
     * "deviceId":"+xkVOHTXVzFOpP+YzyHsZhFbn4ldgiWXGZ/eGL5NHB7hXTn46LeqOPfYQk+YO9QL",
     * "tenantId":"1103","transType":"00","authType":"00"}]}
     */
    public String getDeviceInfo(String request) {

        LOG.info("[/device/info][begin]");
        ServerContext.getServerContext().getFidoLog().setRequest(request);
        Gson gson = UAFSchemaBuilder.getGson();
//        FidoRespPayload<List<UserInfoBean>> respPayload = new FidoRespPayload<List<UserInfoBean>>();
        FidoRespPayload<String> respPayload = new FidoRespPayload<String>();
        Type reqType = new TypeToken<ReceiveReqPayload<GetUserInfoContext>>() {
        }.getType();

        String response;
        try {
            ReceiveReqPayload<GetUserInfoContext> reqPayload = gson.fromJson(request, reqType);
            //记录日志
            logRequest(request, reqPayload.getContext().getTransNo(), null,
                    reqPayload.getContext().getAppID(), null, null, Constants.Method.DEVICE_INFO);
            //验证context参数
            validate(reqPayload);
            List<String> transType = new ArrayList<String>();
            transType.add("00");
            transType.add("01");
            transType.add("02");
            List<String> appIDs = new ArrayList<String>();
            for(String tType : transType) {
                String appID = this.getServerConfig().getApplicationID(reqPayload.getContext().getAppID(), tType);
                if(Strings.isNotBlank(appID)){
                    appIDs.add(appID);
                }
            }

           Map<String,List<String>> map = new HashMap<String,List<String>>();
            map.put("appIDs",appIDs);

            response = buildReceiveResponse(gson, respPayload, Collections.singletonList(map));
        } catch (Exception ex) {
            LOG.error("[/device/info] ERROR", ex);
            response = buildFidoRespFromException(respPayload, ex);
        }
        LOG.info("[/device/info][end]");
        return response;
    }

    /**
     * 验证context参数
     *
     * @param reqPayload
     * @throws PayloadValidationException
     */
    private void validate(ReceiveReqPayload<GetUserInfoContext> reqPayload)
            throws PayloadValidationException, UnsupportedEncodingException {
        if ((reqPayload == null) || (reqPayload.getContext() == null)) {
            throw new PayloadValidationException("context", RestValidator.VALIDATION_ERROR.EMPTY);
        }
        RestValidator.validate("appID", reqPayload.getContext().getAppID());
        RestValidator.validate("deviceID", reqPayload.getContext().getDeviceID());
        RestValidator.validate("transNo", reqPayload.getContext().getTransNo());

    }
}
